home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk57 / pdmake / make.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  5KB  |  286 lines

  1. /***************************************************************\
  2. *                                *
  3. *  PDMAKE, Atari ST version                    *
  4. *                                *
  5. *  Adapted from mod.sources Vol 7 Issue 71, 1986-12-03.        *
  6. *                                *
  7. *  This port makes extensive use of the original net.sources    *
  8. *  port by Jwahar Bammi.                    *
  9. *                                *
  10. *      Ton van Overbeek                        *
  11. *      Email: TPC862@ESTEC.BITNET                *
  12. *             TPC862%ESTEC.BITNET@WISCVM.WISC.EDU    (ARPA)    *
  13. *             ...!mcvax!tpc862%estec.bitnet   (UUCP Europe)    *
  14. *             ...!ucbvax!tpc862%estec.bitnet  (UUCP U.S.A.)    *
  15. *             71450,3537  (CompuServe)                *
  16. *                                *
  17. \***************************************************************/
  18.  
  19. /*
  20.  *    Do the actual making for make
  21.  */
  22.  
  23. #include <stdio.h>
  24.  
  25. #include "astat.h"
  26. #include "h.h"
  27.  
  28. /*
  29.  *    Exec a shell that returns exit status correctly (/bin/esh).
  30.  *    The standard EON shell returns the process number of the last
  31.  *    async command, used by the debugger (ugg).
  32.  *    [exec on eon is like a fork+exec on unix]
  33.  */
  34. int
  35. dosh(string, shell)
  36. char    *string;
  37. char    *shell;
  38. {
  39.     int    number;
  40.  
  41.     return system(string);
  42. }
  43.  
  44.  
  45. /*
  46.  *    Do commands to make a target
  47.  */
  48. void
  49. docmds1(np, lp)
  50. struct name *       np;
  51. struct line *       lp;
  52. {
  53.     bool    ssilent;
  54.     bool    signore;
  55.     int    estat;
  56.     register char    *q;
  57.     register char    *p;
  58.     char    *shell;
  59.     register struct cmd *cp;
  60.  
  61.     if (*(shell = getmacro("SHELL")) == '\0')
  62.         ;
  63.  
  64.     for (cp = lp->l_cmd; cp; cp = cp->c_next) {
  65.         strcpy(str1, cp->c_cmd);
  66.         expand(str1);
  67.         q = str1;
  68.         ssilent = silent;
  69.         signore = ignore;
  70.         while ((*q == '@') || (*q == '-')) {
  71.             if (*q == '@')       /*  Specific silent  */
  72.                 ssilent = TRUE;
  73.             else /*  Specific ignore  */
  74.                 signore = TRUE;
  75.             q++;           /*  Not part of the command  */
  76.         }
  77.  
  78.         if (!domake)
  79.             ssilent = 0;
  80.  
  81.         if (!ssilent)
  82.             fputs("    ", stdout);
  83.  
  84.         for (p = q; *p; p++) {
  85.             if (*p == '\n' && p[1] != '\0') {
  86.                 *p = ' ';
  87.                 if (!ssilent)
  88.                     fputs("\\\n", stdout);
  89.             } else if (!ssilent)
  90.                 putchar(*p);
  91.         }
  92.         if (!ssilent)
  93.             putchar('\n');
  94.  
  95.         if (domake) {            /*  Get the shell to execute it  */
  96.             if ((estat = dosh(q, shell)) != 0) {
  97.                 if (estat == -1)
  98.                     fatal("Couldn't execute %s", q);
  99.                 else {
  100.                     printf("%s: Error code %d", myname, estat);
  101.                     if (signore)
  102.                         fputs(" (Ignored)\n", stdout);
  103.                     else {
  104.                         putchar('\n');
  105.                         if (!(np->n_flag & N_PREC))
  106.                             if (unlink(np->n_name) == 0)
  107.                                 printf("%s: '%s' removed.\n", myname,
  108.                                     np->n_name);
  109.                         exit(estat);
  110.                     }
  111.                 }
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117.  
  118. docmds(np)
  119. struct name *np;
  120. {
  121.     register struct line *lp;
  122.  
  123.  
  124.     for (lp = np->n_line; lp; lp = lp->l_next)
  125.         docmds1(np, lp);
  126. }
  127.  
  128.  
  129. /*
  130.  *    Get the current time in the internal format
  131.  */
  132. time(tp)
  133. time_t *tp;
  134. {
  135.     if (tp)
  136.         *tp = Gettime();
  137.  
  138.     return 0;
  139. }
  140.  
  141.  
  142. /*
  143.  *    Get the modification time of a file.  If the first
  144.  *    doesn't exist, it's modtime is set to 0.
  145.  */
  146. void
  147. modtime(np)
  148. struct name *np;
  149. {
  150.     struct stat info;
  151.     extern int    getstat();        /*  in ststuff.c  */
  152.     extern void        FlipWords();        /*  in ststuff.c  */
  153.  
  154.     if (getstat(np->n_name, &info) < 0)
  155.         np->n_time = 0L;
  156.     else {
  157.         FlipWords(&info.st_mod);
  158.         np->n_time = info.st_mod;
  159.     }
  160. }
  161.  
  162.  
  163. /*
  164.  *    Update the mod time of a file to now.
  165.  */
  166. void
  167. touch(np)
  168. struct name *np;
  169. {
  170.     char    c;
  171.     int    fd;
  172.  
  173.  
  174.     if (!domake || !silent)
  175.         printf("    touch(%s)\n", np->n_name);
  176.  
  177.     if (domake) {
  178.         if ((fd = Fopen(np->n_name, 0)) < 0)
  179.             printf("%s: '%s' not touched - non-existant\n",
  180.                 myname, np->n_name);
  181.         else {
  182.             long    tim;
  183.  
  184.             tim = Gettime();
  185.             FlipWords(&tim);
  186.             if (Fdatime( &tim, fd, 1) < 0)
  187.                 printf("%s: '%s' not touched - disk protected ?\n",
  188.                     myname, np->n_name);
  189.             Fclose(fd);
  190.         }
  191.     }
  192. }
  193.  
  194.  
  195. /*
  196.  *    Recursive routine to make a target.
  197.  */
  198. int
  199. make(np, level)
  200. struct name *    np;
  201. int    level;
  202. {
  203.     register struct depend *dp;
  204.     register struct line *lp;
  205.     register struct depend *qdp;
  206.     time_t    dtime = 1;
  207.     bool    didsomething = 0;
  208.  
  209.  
  210.     if (np->n_flag & N_DONE)
  211.         return 0;
  212.  
  213.     if (!np->n_time)
  214.         modtime(np);    /*  Gets modtime of this file  */
  215.  
  216.     if (rules) {
  217.         for (lp = np->n_line; lp; lp = lp->l_next)
  218.             if (lp->l_cmd)
  219.                 break;
  220.         if (!lp)
  221.             dyndep(np);
  222.     }
  223.  
  224.     if (!(np->n_flag & N_TARG) && np->n_time == 0L)
  225.         fatal("Don't know how to make %s", np->n_name);
  226.  
  227.     for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next) {
  228.         for (dp = lp->l_dep; dp; dp = dp->d_next) {
  229.             make(dp->d_name, level + 1);
  230.             if (np->n_time < dp->d_name->n_time)
  231.                 qdp = newdep(dp->d_name, qdp);
  232.             dtime = max(dtime, dp->d_name->n_time);
  233.         }
  234.         if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) {
  235.             make1(np, lp, qdp);        /* free()'s qdp */
  236.             dtime = 1;
  237.             qdp = (struct depend *)0;
  238.             didsomething++;
  239.         }
  240.     }
  241.  
  242.     np->n_flag |= N_DONE;
  243.  
  244.     if (quest) {
  245.         long    t;
  246.  
  247.         t = np->n_time;
  248.         time(&np->n_time);
  249.         return t < dtime;
  250.     } else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) {
  251.         make1(np, (struct line *)0, qdp);    /* free()'s qdp */
  252.         time(&np->n_time);
  253.     } else if (level == 0 && !didsomething)
  254.         printf("%s: '%s' is up to date\n", myname, np->n_name);
  255.     return 0;
  256. }
  257.  
  258.  
  259. make1(np, lp, qdp)
  260. register struct depend *qdp;
  261. struct line *lp;
  262. struct name *np;
  263. {
  264.     register struct depend *dp;
  265.  
  266.  
  267.     if (dotouch)
  268.         touch(np);
  269.     else {
  270.         strcpy(str1, "");
  271.         for (dp = qdp; dp; dp = qdp) {
  272.             if (strlen(str1))
  273.                 strcat(str1, " ");
  274.             strcat(str1, dp->d_name->n_name);
  275.             qdp = dp->d_next;
  276.             free(dp);
  277.         }
  278.         setmacro("?", str1);
  279.         setmacro("@", np->n_name);
  280.         if (lp)            /* lp set if doing a :: rule */
  281.             docmds1(np, lp);
  282.         else
  283.             docmds(np);
  284.     }
  285. }
  286.